
import processing.core.*;
import java.util.*;
import java.awt.Point;

class Forma extends PApplet implements Cloneable {

    public int puntoMatrizResultado[][];
    public ArrayList vertices;
    public int red, green, blue;
    public int parametroBeginShape;
    public int parametroEndShape;

    Forma() {
        red = green = blue = 0;
        vertices = new ArrayList();
        parametroEndShape = -1;
        parametroBeginShape = -1;
    }

    void setColorRelleno(int r, int g, int b) {
        red = r;
        green = g;
        blue = b;
    }

    void multiplicarMatrices(double matriz1[][], double matriz2[][]) {
        int filas1ra = matriz1.length;
        int columnas1ra = matriz1[0].length;//Se toma la fila 0 pero podría haber
        //sido cualquier otra que estuviera definida

        int filas2da = matriz2.length;
        int columnas2da = matriz2[0].length;

        if (columnas1ra != filas2da) {
            System.out.println("Estas matrices no pueden ser multiplicadas");
            //ABortar ejecución
            System.exit(0);
        }

        this.puntoMatrizResultado = new int[filas1ra][columnas2da];

        for (int i = 0; i < columnas2da; i++) {
            for (int e = 0; e < filas1ra; e++) {
                int resFilaActual = 0;
                for (int u = 0; u < filas2da; u++) {
                    resFilaActual += matriz1[e][u] * matriz2[u][i];
                }

                puntoMatrizResultado[e][i] = resFilaActual;

            }
        }
    }

    public void dibujar(PGraphics pg, boolean conRelleno) {
        pg.beginDraw();
        if (parametroBeginShape == -1) {
            pg.beginShape();
        } else {
            pg.beginShape(parametroBeginShape);
        }
        if (conRelleno) {
            pg.fill(red, green, blue);
        }else {
            pg.noFill();
        }

        Iterator iteradorAl = vertices.iterator();
        while (iteradorAl.hasNext()) {
            Point punto = (Point) iteradorAl.next();
            pg.vertex(punto.x, punto.y);
        }
        if (parametroEndShape == -1) {
            pg.endShape();
        } else {
            pg.endShape(parametroEndShape);
        }
        pg.endDraw();
    }

    void trasladar(int dx, int dy) {
        double matrizTransformacion[][] = {{1, 0, dx}, {0, 1, dy}, {0, 0, 1}};
        Iterator iteradorAl = vertices.iterator();
        while (iteradorAl.hasNext()) {
            Point punto = (Point) iteradorAl.next();
            double[][] matrizPunto = {{punto.x}, {punto.y}, {1}};
            multiplicarMatrices(matrizTransformacion, matrizPunto);
            punto.x = puntoMatrizResultado[0][0];
            punto.y = puntoMatrizResultado[1][0];
        }
    }

    void girar(int grados) {
        double gradosRad = Math.toRadians(grados);
        double cosAngulo = Math.cos(gradosRad);
        double senAngulo = Math.sin(gradosRad);

        double matrizTransformacion[][] = {{cosAngulo, senAngulo * -1, 0}, {senAngulo, cosAngulo, 0}, {0, 0, 1}};

        Iterator iteradorAl = vertices.iterator();
        while (iteradorAl.hasNext()) {
            Point punto = (Point) iteradorAl.next();
            double[][] matrizPunto = {{punto.x}, {punto.y}, {1}};
            multiplicarMatrices(matrizTransformacion, matrizPunto);
            punto.x = puntoMatrizResultado[0][0];
            punto.y = puntoMatrizResultado[1][0];
        }
    }

    void escalar(double factorEscalacion) {
        double matrizTransformacion[][] = {{factorEscalacion, 0, 0}, {0, factorEscalacion, 0}, {0, 0, 1}};
        Iterator iteradorAl = vertices.iterator();
        while (iteradorAl.hasNext()) {
            Point punto = (Point) iteradorAl.next();
            double[][] matrizPunto = {{punto.x}, {punto.y}, {1}};
            multiplicarMatrices(matrizTransformacion, matrizPunto);
            punto.x = puntoMatrizResultado[0][0];
            punto.y = puntoMatrizResultado[1][0];
        }
    }

    public Object clone() {
        Object obj = null;
        try {
            obj = super.clone();
        } catch (CloneNotSupportedException ex) {
            System.out.println(" no se puede duplicar");
        }
        return obj;
    }
}
